<template>
    <div style="width: 100%;height: 100%;padding: 5px;">
        <div class="search-box">
            <el-form-item label="位置">
                <el-select v-model="address" clearable placeholder="请输入位置关键词" style="width: 240px;"
                    :remote-method="remoteMethod" filterable remote @change="currentSelect" class="one-text"
                    size="default">
                    <el-option v-for="(item, index) in areaList" :key="index" :label="item.district + item.name"
                        :value="item.district + item.name">
                        <span>{{ item.district }}</span> <span>{{ item.name }}</span>
                    </el-option>
                </el-select>
            </el-form-item>

            <el-button type="primary" v-if="addressGet" class="address">{{ addressGet.split(",")[0] }}</el-button>
        </div>
        <div id="container" class="map"></div>
    </div>
</template>

<script setup>
import { reactive, ref, toRefs, onMounted, onUnmounted, nextTick } from 'vue';
import AMapLoader from "@amap/amap-jsapi-loader";

// 定义 props 和 emits
const emits = defineEmits(['address']);
const props = defineProps({
    addressClick: Function
})
onMounted(() => {
    window._AMapSecurityConfig = {
        securityJsCode: '8ffe92977bb0f5d65f8cf83a59a5186b', // https://console.amap.com/dev/key/app   绑定的服务为 Web端
    }
    //清除之前的加载状态
    AMapLoader.reset()
    //初始化地图
    initMap()
})

onUnmounted(() => {
    console.log("GaoDeMap.vue 销毁地图===")
    state.map?.destroy();
})

const addressGet = ref("")

const state = reactive({
    map: null,
    placeSearch: null,
    autoComplete: null,
    marker: null,
    form: {
        address: '',
        lng: '',
        lat: '',
    },
    areaList: [],
    address: ''
})

const { areaList, address } = toRefs(state)
function initMap(arr) {
    AMapLoader.load({
        key: "c589dad363492c5cd9ba0b62950a9dc8",	// https://console.amap.com/dev/key/app   绑定的服务为 Web端
        version: "2.0",
        //AMap.ToolBar 工具条，控制地图的缩放、平移等
        //AMap.ControlBar 组合了旋转、倾斜、复位在内的地图控件
        //AMap.AutoComplete 输入提示，提供了根据关键字获得提示信息的功能
        //AMap.PlaceSearch 	地点搜索服务，提供了关键字搜索、周边搜索、范围内搜索等功能
        //AMap.Geocoder 地理编码与逆地理编码服务，提供地址与坐标间的相互转换
        //AMap.Marker
        //AMap.Geolocation 浏览器定位，提供了获取用户当前准确位置、所在城市的方法
        plugins: ["AMap.ToolBar", "AMap.ControlBar", 'AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.Marker', 'AMap.Geolocation'],
    }).then((AMap) => {
        state.map = new AMap.Map('container', {
            viewMode: "3D",  //  是否为3D地图模式
            zoom: 15,
            center: arr,
            resizeEnable: true
        });
        // 地图放大缩小插件
        let toolBar = new AMap.ToolBar({
            position: {
                top: '120px',
                right: '50px'
            }
        })
        // 3D地图插件
        let controlBar = new AMap.ControlBar({
            position: {
                top: '20px',
                right: '22px',
            },
        });

        state.geoCoder = new AMap.Geocoder({
            city: '010', //城市设为北京，默认：“全国”
            radius: 1000 //范围，默认：500
        });

        // 正向地理编码
        state.geocoder = new AMap.Geocoder({
            city: state.address
        })
        // 定位
        let geolocation = new AMap.Geolocation({
            enableHighAccuracy: true, // 是否使用高精度定位，默认:true
            timeout: 10000, // 超过10秒后停止定位，默认：5s
            // 定位按钮的停靠位置
            position: {
                top: '200px',
                right: '50px',
            }, 
            buttonOffset: new AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
            zoomToAccuracy: true, // 定位成功后是否自动调整地图视野到定位点
        });


        geolocation.on('error', (error) => {
            console.error('定位失败:', error);
            // 处理定位失败的逻辑
        });

        state.autoComplete = new AMap.AutoComplete({ city: '全国' });
        state.map.setDefaultCursor("pointer"); // 使用CSS默认样式定义地图上的鼠标样式
        state.map.on('click', (e) => { // 点击地图事件
            if (!e && !e.lnglat) {
                return
            }
            state.form.lng = e.lnglat.lng
            state.form.lat = e.lnglat.lat
            removeMarker() // 先删除地图上标记点
            setMapMarker() // 在添加新的标记点
        })
        state.map.addControl(toolBar);   // 添加右上角的放大缩小
        state.map.addControl(controlBar);   // 添加右上角的放大缩小
        state.map.addControl(geolocation);   // 添加右上角的放大缩小
        // 监听定位成功事件
    }).catch((e) => {
        console.error(e);  //加载错误提示
    }).finally(() => {
        removeMarker()
        setMapMarker()
    })

}

function setMapMarker() {
    if (state.form.lng == '' && state.form.lat == '') {
        return
    }
    state.map.setFitView()
    state.marker = new AMap.Marker({
        map: state.map,
        position: [state.form.lng, state.form.lat],
    })
    toGetAddress()
    state.map.setFitView()
    state.map.add(state.marker)
}

function removeMarker() {
    if (state.marker) {
        state.map.remove(state.marker)
    }
}

function toGetAddress() {
    let lnglat = [state.form.lng, state.form.lat]
    state.geoCoder.getAddress(lnglat, (status, result) => {
        console.log('get address result: ', result)
        if (status === 'complete' && result.regeocode) {
            props.addressClick(result, state.form.lng, state.form.lat) // 返回位置信息以及经纬度
            addressGet.value = `${result.regeocode.formattedAddress},${state.form.lng},${state.form.lat}`
        }
    })
}

function remoteMethod(query) {
    if (query !== '') {
        setTimeout(() => {
            state.autoComplete.search(query, (status, result) => {
                state.areaList = result.tips
            })
        }, 500)
    } else {
        state.areaList = []
    }
}
function currentSelect(val) {
    if (!val) {
        return
    }
    toGetCoordinate(val)
}

function toGetCoordinate(address) {
    state.geocoder.getLocation(address, function (status, result) {
        if (status === 'complete' && result.info === 'OK') {
            initMap([result.geocodes[0].location.lng, result.geocodes[0].location.lat])
            state.form.lng = result.geocodes[0].location.lng
            state.form.lat = result.geocodes[0].location.lat
            state.form.address = `${result.geocodes[0].formattedAddress}`

            // 返回给父组件的值
            emits("address", `${result.geocodes[0].formattedAddress},${result.geocodes[0].location.lng},${result.geocodes[0].location.lat}`);
        }
    })
    nextTick(function () {
        removeMarker()
        setMapMarker()
    })
}

function fixed(lng, lat) {
    initMap([lng, lat])
    state.form.lng = lng
    state.form.lat = lat
}


// 暴露方法
defineExpose({
    fixed,
    toGetCoordinate
});
</script>



<style scoped lang="scss">
.search-box {
    display: flex;
    height: 20px;
    padding: 5px;
}

.address {
    margin-left: 20px;
}

.map {
    margin-top: 20px;
    border-radius: 5px;
    width: 100%;
    height: 100%;
}

</style>